﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Eacademy.Domain.Abstractions;
using Eacademy.Domain.Repository;
using Eacademy.Domain.Services;
using Eacademy.Library.Routes;
using Eacademy.Library.Validations;
using Elmah;
using Ninject;
using Ninject.Modules;
using Ninject.Web.Mvc;
using XCaptcha.Web.Mvc;
using Eacademy.Library.Membership;
using System.Web.Security;
using Eacademy.Library.Helpers;

namespace Eacademy
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : NinjectHttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRouteLowerCase(
                "Register",
                "Account/{usertype}/Register",
                new { controller = "Account", action = "Register", usertype = "Member" }
            );

            routes.MapRouteLowerCase(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { area = "" , controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
                new string[] { "Eacademy.Controllers" }
            );

            //Captcha controller
            RouteBuilder.Default.Map(routes, "Captcha");
        }

        protected void Session_Start(Object sender, EventArgs e)
        {
            var provider = (CustomMembershipProvider)Membership.Provider;
            IUserRepository userRepository = new UserRepository();


            if (Request.IsAuthenticated && provider.User == null)
            {
                Domain.Models.User user = userRepository.GetUserByUsername(HttpContext.Current.User.Identity.Name);
                string encryptedCookie = Request.Cookies[FormsAuthentication.FormsCookieName].Value;
                FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encryptedCookie);

                if (user != null)
                {
                    user.UserType = UserHelper.GetUserTypeById(user.UserTypeId);
                    user.Identification = ticket.UserData;
                    provider.User = user;
                }
                else
                {
                    FormsAuthentication.SignOut();
                }
            }
            else
            {
                FormsAuthentication.SignOut();
                FormsAuthentication.RedirectToLoginPage();
            }
        }

        protected void Application_BeginRequest(object sender, EventArgs e)
        {

            /* we guess at this point session is not already retrieved by application so we recreate cookie with the session id... */
            try
            {
                string session_param_name = "si";
                string session_cookie_name = "ASP.NET_SessionId";

                if (HttpContext.Current.Request.Form[session_param_name] != null)
                {
                    UpdateCookie(session_cookie_name, HttpContext.Current.Request.Form[session_param_name]);
                }
                else if (HttpContext.Current.Request.QueryString[session_param_name] != null)
                {
                    UpdateCookie(session_cookie_name, HttpContext.Current.Request.QueryString[session_param_name]);
                }
            }
            catch
            {
            }

            try
            {
                string auth_param_name = "authtoken";
                string auth_cookie_name = FormsAuthentication.FormsCookieName;

                if (HttpContext.Current.Request.Form[auth_param_name] != null)
                {
                    UpdateCookie(auth_cookie_name, HttpContext.Current.Request.Form[auth_param_name]);
                }
                else if (HttpContext.Current.Request.QueryString[auth_param_name] != null)
                {
                    UpdateCookie(auth_cookie_name, HttpContext.Current.Request.QueryString[auth_param_name]);
                }

            }
            catch
            {
            }
        }

        private void UpdateCookie(string cookie_name, string cookie_value)
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);
            if (null == cookie)
            {
                cookie = new HttpCookie(cookie_name);
            }
            cookie.Value = cookie_value;
            HttpContext.Current.Request.Cookies.Set(cookie);
        }

        protected override void OnApplicationStarted()
        {

            //removes X-AspNetMvc-Version header
            MvcHandler.DisableMvcResponseHeader = true;

            AreaRegistration.RegisterAllAreas();

            RegisterRoutes(RouteTable.Routes);

            //**Custom Validation Adapters
            ValidationDataAnnotationsProvider.RegisterAdapters();
        }

        static IKernel _container;
        public static IKernel Container
        {
            get
            {
                if (_container == null)
                {
                    _container = new StandardKernel(new SiteModule());
                }
                return _container;
            }
        }

        internal class SiteModule : NinjectModule
        {
            public override void Load()
            {
                Bind<IUserRepository>().To<UserRepository>();
                Bind<ISearchSuggestor>().To<GoogleSearchSuggestor>();
                Bind<ISubjectRepository>().To<SubjectRepository>();
                Bind<IStudentRepository>().To<StudentRepository>();
                Bind<IMentorRepository>().To<MentorRepository>();
                Bind<ILessonRepository>().To<LessonRepository>();
                Bind<IQuizRepository>().To<QuizRepository>();
                Bind<IMessageRepository>().To<MessageRepository>();
                Bind<IAssessmentRepository>().To<AssessmentRepository>();
                Bind<IAssignmentRepository>().To<AssignmentRepository>();
            }
        }

        protected override IKernel CreateKernel()
        {
            return Container;
        }
    }
}